home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / tex / cm_mf.arc / PLAIN.MF < prev   
Text File  |  1989-01-30  |  22KB  |  586 lines

  1. % This is the plain METAFONT base that's described in The METAFONTbook.
  2. % N.B.: Please change "base_version" whenever this file is modified!
  3. % And don't modify the file under any circumstances.
  4. string base_name, base_version; base_name="plain"; base_version="1.0";
  5.  
  6. message "Preloading the plain base, version "&base_version&": preliminaries,";
  7.  
  8. delimiters ();  % this makes parentheses behave like parentheses
  9. def upto = step 1 until enddef; % syntactic sugar
  10. def downto = step -1 until enddef;
  11. def exitunless expr c = exitif not c enddef;
  12. let relax = \;  % ignore the word `relax', as in TeX
  13. let \\ = \; % double relaxation is like single
  14. def ]] = ] ] enddef; % right brackets should be loners
  15. def -- = {curl 1}..{curl 1} enddef;
  16. def --- = .. tension infinity .. enddef;
  17. def ... = .. tension atleast 1 .. enddef;
  18.  
  19. def gobble primary g = enddef;
  20. primarydef g gobbled gg = enddef;
  21. def hide(text t) = exitif numeric begingroup t;endgroup; enddef;
  22. def ??? = hide(interim showstopping:=1; showdependencies) enddef;
  23. def stop expr s = message s; gobble readstring enddef;
  24.  
  25. smoothing:=1; autorounding:=2;  % this adjusts curves to the raster
  26. turningcheck:=2;                % this will warn about a "strange path"
  27. granularity:=1;                 % this says that pixels are pixels
  28.  
  29. def interact = % sets up to make "show" commands stop
  30.  hide(showstopping:=1; tracingonline:=1) enddef;
  31.  
  32. def loggingall =        % puts tracing info into the log
  33.  tracingcommands:=3; tracingedges:=2; tracingtitles:=1; tracingequations:=1;
  34.  tracingcapsules:=1; tracingspecs:=1; tracingpens:=1; tracingchoices:=1;
  35.  tracingstats:=1; tracingoutput:=1; tracingmacros:=1; tracingrestores:=1;
  36.  enddef;
  37.  
  38. def tracingall =        % turns on every form of tracing
  39.  tracingonline:=1; showstopping:=1; loggingall enddef;
  40.  
  41. def tracingnone =       % turns off every form of tracing
  42.  tracingcommands:=0; tracingonline:=0; showstopping:=0;
  43.  tracingedges:=0; tracingtitles:=0; tracingequations:=0;
  44.  tracingcapsules:=0; tracingspecs:=0; tracingpens:=0; tracingchoices:=0;
  45.  tracingstats:=0; tracingoutput:=0; tracingmacros:=0; tracingrestores:=0;
  46.  enddef;
  47.  
  48. message " basic constants and mathematical macros,";
  49.  
  50. % numeric constants
  51. newinternal eps,epsilon,infinity,_;
  52. eps := .00049;    % this is a pretty small positive number
  53. epsilon := 1/256/256;   % but this is the smallest
  54. infinity := 4095.99998;    % and this is the largest
  55. _ := -1; % internal constant to make macros unreadable but shorter
  56.  
  57. % pair constants
  58. pair right,left,up,down,origin;
  59. origin=(0,0); up=-down=(0,1); right=-left=(1,0);
  60.  
  61. % path constants
  62. path quartercircle,halfcircle,fullcircle,unitsquare;
  63. quartercircle=(right{up}..(right+up)/sqrt2..up{left}) scaled .5;
  64. halfcircle=quartercircle & quartercircle rotated 90;
  65. fullcircle=halfcircle & halfcircle rotated 180 & cycle;
  66. unitsquare=(0,0)--(1,0)--(1,1)--(0,1)--cycle;
  67.  
  68. % transform constants
  69. transform identity;
  70. for z=origin,right,up: z transformed identity = z; endfor
  71.  
  72. % picture constants
  73. picture blankpicture,unitpixel;
  74. blankpicture=nullpicture; % `display blankpicture...'
  75. unitpixel=nullpicture; addto unitpixel contour unitsquare;
  76.  
  77. % string constants
  78. string ditto; ditto = char 34; % ASCII double-quote mark
  79.  
  80. % pen constants
  81. def capsule_def(suffix s) primary u = def s = u enddef enddef;
  82. capsule_def(pensquare) makepen(unitsquare shifted -(.5,.5));
  83. capsule_def(penrazor) makepen((-.5,0)--(.5,0)--cycle);
  84. pen penspeck; penspeck=pensquare scaled eps;
  85.  
  86. % nullary operators
  87. vardef whatever = save ?; ? enddef;
  88.  
  89. % unary operators
  90. let abs = length;
  91.  
  92. vardef round primary u =
  93.  if numeric u: floor(u+.5)
  94.  elseif pair u: (hround xpart u, vround ypart u)
  95.  else: u fi enddef;
  96.  
  97. vardef hround primary x = floor(x+.5) enddef;
  98. vardef vround primary y = floor(y.o_+.5)_o_ enddef;
  99.  
  100. vardef ceiling primary x = -floor(-x) enddef;
  101.  
  102. vardef byte primary s =
  103.  if string s: ASCII fi s enddef;
  104.  
  105. vardef dir primary d = right rotated d enddef;
  106.  
  107. vardef unitvector primary z = z/abs z enddef;
  108.  
  109. vardef inverse primary T =
  110.  transform T_; T_ transformed T = identity; T_ enddef;
  111.  
  112. vardef counterclockwise primary c =
  113.  interim autorounding:=0;
  114.  if turningnumber c <= 0: reverse fi c enddef;
  115.  
  116. vardef tensepath expr r =
  117.  for k=0 upto length r - 1: point k of r --- endfor
  118.  if cycle r: cycle else: point infinity of r fi enddef;
  119.  
  120. % binary operators
  121.  
  122. primarydef x mod y = (x-y*floor(x/y)) enddef;
  123. primarydef x div y = floor(x/y) enddef;
  124. primarydef w dotprod z = (xpart w * xpart z + ypart w * ypart z) enddef;
  125.  
  126. primarydef x**y = if y=2: x*x else: takepower y of x fi enddef;
  127. def takepower expr y of x =
  128.  if x>0: mexp(y*mlog x)
  129.  elseif (x=0) and (y>0): 0
  130.  else: 1
  131.   if y=floor y:
  132.    if y>=0: for n=1 upto y: *x endfor
  133.    else: for n=_ downto y: /x endfor
  134.    fi
  135.   else: hide(errmessage "Undefined power: " & decimal x&"**"&decimal y)
  136.   fi fi enddef;
  137.  
  138. vardef direction expr t of p =
  139.  postcontrol t of p - precontrol t of p enddef;
  140.  
  141. vardef directionpoint expr z of p =
  142.  a_:=directiontime z of p;
  143.  if a_<0: errmessage("The direction doesn't occur"); fi
  144.  point a_ of p enddef;
  145.  
  146. secondarydef p intersectionpoint q =
  147.  begingroup save x_,y_; (x_,y_)=p intersectiontimes q;
  148.  if x_<0: errmessage("The paths don't intersect"); origin
  149.  else: .5[point x_ of p, point y_ of q] fi endgroup
  150. enddef;
  151.  
  152. tertiarydef p softjoin q =
  153.  begingroup c_:=fullcircle scaled 2join_radius shifted point 0 of q;
  154.  a_:=ypart(c_ intersectiontimes p); b_:=ypart(c_ intersectiontimes q);
  155.  if a_<0:point 0 of p{direction 0 of p} else: subpath(0,a_) of p fi
  156.   ... if b_<0:{direction infinity of q}point infinity of q
  157.    else: subpath(b_,infinity) of q fi endgroup enddef;
  158. newinternal join_radius,a_,b_; path c_;
  159.  
  160. % special operators
  161. vardef incr suffix $ = $:=$+1; $ enddef;
  162. vardef decr suffix $ = $:=$-1; $ enddef;
  163.  
  164. def reflectedabout(expr w,z) =    % reflects about the line w..z
  165.  transformed
  166.   begingroup transform T_;
  167.   w transformed T_ = w;  z transformed T_ = z;
  168.   xxpart T_ = -yypart T_; xypart T_ = yxpart T_; % T_ is a reflection
  169.   T_ endgroup enddef;
  170.  
  171. def rotatedaround(expr z, d) =    % rotates d degrees around z
  172.  shifted -z rotated d shifted z enddef;
  173. let rotatedabout = rotatedaround;   % for roundabout people
  174.  
  175. vardef min(expr u)(text t) = % t is a list of numerics, pairs, or strings
  176.  save u_; setu_ u; for uu = t: if uu<u_: u_:=uu; fi endfor
  177.  u_ enddef;
  178.  
  179. vardef max(expr u)(text t) = % t is a list of numerics, pairs, or strings
  180.  save u_; setu_ u; for uu = t: if uu>u_: u_:=uu; fi endfor
  181.  u_ enddef;
  182.  
  183. def setu_ primary u =
  184.  if pair u: pair u_ elseif string u: string u_ fi;
  185.  u_=u enddef;
  186.  
  187. def flex(text t) =           % t is a list of pairs
  188.  hide(n_:=0; for z=t: z_[incr n_]:=z; endfor
  189.   dz_:=z_[n_]-z_1)
  190.  z_1 for k=2 upto n_-1: ...z_[k]{dz_} endfor ...z_[n_] enddef;
  191. newinternal n_; pair z_[],dz_;
  192.  
  193. def superellipse(expr r,t,l,b,s)=
  194.  r{up}...(s[xpart t,xpart r],s[ypart r,ypart t]){t-r}...
  195.  t{left}...(s[xpart t,xpart l],s[ypart l,ypart t]){l-t}...
  196.  l{down}...(s[xpart b,xpart l],s[ypart l,ypart b]){b-l}...
  197.  b{right}...(s[xpart b,xpart r],s[ypart r,ypart b]){r-b}...cycle enddef;
  198.  
  199. vardef interpath(expr a,p,q) =
  200.  for t=0 upto length p-1: a[point t of p, point t of q]
  201.   ..controls a[postcontrol t of p, postcontrol t of q]
  202.    and a[precontrol t+1 of p, precontrol t+1 of q] .. endfor
  203.  if cycle p: cycle
  204.  else: a[point infinity of p, point infinity of q] fi enddef;
  205.  
  206. vardef solve@#(expr true_x,false_x)= % @#(true_x)=true, @#(false_x)=false
  207.  tx_:=true_x; fx_:=false_x;
  208.  forever: x_:=.5[tx_,fx_]; exitif abs(tx_-fx_)<=tolerance;
  209.  if @#(x_): tx_ else: fx_ fi :=x_; endfor
  210.  x_ enddef; % now x_ is near where @# changes from true to false
  211. newinternal tolerance, tx_,fx_,x_; tolerance:=.1;
  212.  
  213. message " macros for converting from device-independent units to pixels,";
  214.  
  215. def fix_units =  % define the conversion factors, given pixels_per_inch
  216.  mm:=pixels_per_inch/25.4;      cm:=pixels_per_inch/2.54;
  217.  pt:=pixels_per_inch/72.27;     pc:=pixels_per_inch/6.0225;
  218.  dd:=1238/1157pt;               cc:=12dd;
  219.  bp:=pixels_per_inch/72;        in:=pixels_per_inch;
  220.  hppp:=pt;                      % horizontal pixels per point
  221.  vppp:=aspect_ratio*hppp;       % vertical pixels per point
  222.  enddef;
  223.  
  224. mm#=2.84528;      pt#=1;        dd#=1.07001;      bp#:=1.00375;
  225. cm#=28.45276;     pc#=12;